import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Menu } from './entities/menu.entity';
import { In, Repository, TreeRepository } from 'typeorm';
import { CreateMenuDto } from './dto/create.menu.dto';
import { Meta } from './entities/meta.entity';
import { permission } from 'process';
import { Permission } from './entities/menu.permission.entity';

@Injectable()
export class MenuService {
  constructor(
    @InjectRepository(Menu)
    private readonly menuRep: Repository<Menu>,
    @InjectRepository(Permission)
    private readonly perRep: Repository<Permission>,
  ) { }

  async findOne(id: string) {
    const menuData = await this.menuRep.findOneBy({ id });
    // console.log(menuData);
    return menuData;
  }

  async findPermission(menu) {
    // console.log(menu);
    const menuData = await this.menuRep.findOne({
      where: { id: menu.id },
      relations: ["permission"]
    })
    // console.log(menuData);
    return menuData
  }

  async findAllParentMenu(id: string) {
    const treeRep = this.menuRep as any
    const ancestors = await treeRep.findAncestors(id, {
      relations: ["meta"],
    })
    return ancestors
  }

  async addPermission(per) {
    const menu = await this.findOne(per.menuId)
    // console.log(per);
    // const perData = await this.menuRep.findOne({ where: { id: per.id }, relations: ["permission"] })
    // console.log(perData);
    const oldPermission = await this.menuRep.findOne({
      where: { id: per.menuId },
      relations: ["permission"]
    })
    console.log(oldPermission);
    menu.permission = oldPermission.permission.concat(per.permission.map((item) => Object.assign(new Permission(), item)))
    // console.log(per);
    const newPermission = await this.menuRep.save(menu)
    // console.log(newPermission);
    return {}
  }

  async updatePermission(per) {
    return this.perRep.save(per.permission)
  }

  async metaFindByIds(ids: string[]) {
    if (!ids) return;
    const metaList = await this.menuRep.find({ where: { id: In(ids) } })
    return metaList
  }

  // 构建树形结构
  buildTree(menus: Menu[], parentId: string = null) {
    // const parent = menus.filter(menu => menu.parentId === "0");
    // const children = menus.filter(menu => menu.parentId !== "0");

    let children = []

    const parent = menus.filter(menu => {
      if (menu.parentId === "0") {
        return true
      }
      children.push(menu)
      return false
    });

    const filterChildren = (parentId: string) => {
      const OnlyChildren = []
      let filterArr = children.filter(child => {

        if (child.parentId === parentId) {
          return true
        }
        OnlyChildren.push(child)
        return false
      })

      children = OnlyChildren
      if (filterArr.length && OnlyChildren.length) {
        filterArr = filterArr.map(menu => {
          return {
            ...menu,
            children: filterChildren(menu.id)
          }
        })
      }
      return filterArr.length ? filterArr : []
    }

    const menuTree = parent.map(menu => {
      return {
        ...menu,
        children: children.length ? filterChildren(menu.id) : []
      }
    })
    // console.log(menuTree);
    if (children.length) {
      const childrenTree = []
      children.forEach((item) => {
        // console.log("item",item);
        childrenTree.concat(filterChildren(item.id))
      })
      return menuTree.concat(childrenTree).concat(children)
    }

    return menuTree;
  }

  async findAllTrees(menu) {
    const manager = this.menuRep.manager;
    // manager.connection.synchronize();
    // const trees = await manager.getTreeRepository(Menu).findTrees();
    const treeRep = this.menuRep as TreeRepository<Menu>;
    const trees = await treeRep.findTrees({
      relations: ["meta"],
    })
    // console.log(trees);

    const { title } = menu
    // console.log(title);
    const trees1 = await this.menuRep.createQueryBuilder('menu')
      .leftJoinAndSelect('menu.meta', 'meta')
      .innerJoin('menu.meta', 'metaTable', 'metaTable.title LIKE :title', { title: `%${title}%` })
      .getMany();
    const buildTree = this.buildTree(trees1)
    // console.log(buildTree);

    // return trees;
    return trees
  }

  async create(menu: CreateMenuDto) {
    // console.log(menu);
    const { parentId } = menu
    if (parentId) {
      const parentMenu = await this.findOne(parentId)
      menu.parent = parentMenu
    } else {
      menu.parentId = null
    }
    const newMenu = this.menuRep.create(menu)
    const menuData = await this.menuRep.save(newMenu)
    // console.log("menuData", menuData);
    return menuData
  }

  async update(menu) {
    // console.log(menu);
    // console.log(menu);
    // const { parentId } = menu
    // if (parentId) {
    //   const parentMenu = await this.findOne(parentId)
    //   menu.parent = parentMenu
    // } else {
    //   menu.parentId = null
    // }
    // const newMenu = this.menuRep.create(menu)
    const menuData = await this.menuRep.save(menu)
    // console.log("menuData", menuData);
    return menuData
  }

  async remove(menu) {
    const data = await this.menuRep.delete(menu.id)
    return data
  }
}
